﻿using System.Security.Cryptography;

namespace PmSoft.Core.Cryptos;

/// <summary>
/// 对称加密算法工具类
/// </summary>
public class SymmetricCryptoUtility
{
	private readonly SymmetricAlgorithm _symmetricAlgorithm;

	/// <summary>
	/// 构造函数，接受对称加密算法实例
	/// </summary>
	/// <param name="symmetricAlgorithm">对称加密算法</param>
	public SymmetricCryptoUtility(SymmetricAlgorithm symmetricAlgorithm)
	{
		_symmetricAlgorithm = symmetricAlgorithm;
	}

	/// <summary>
	/// 生成加密算法的初始化向量（IV）
	/// </summary>
	/// <returns>Base64编码后的IV</returns>
	public string GenerateIV()
	{
		_symmetricAlgorithm.GenerateIV();
		return Convert.ToBase64String(_symmetricAlgorithm.IV);
	}

	/// <summary>
	/// 生成加密算法的密钥（Key）
	/// </summary>
	/// <returns>Base64编码后的Key</returns>
	public string GenerateKey()
	{
		_symmetricAlgorithm.GenerateKey();
		return Convert.ToBase64String(_symmetricAlgorithm.Key);
	}

	/// <summary>
	/// 解密数据
	/// </summary>
	/// <param name="encryptedData">加密数据</param>
	/// <returns>解密后的字节数组</returns>
	public byte[] Decrypt(byte[] encryptedData)
	{
		using ICryptoTransform decryptor = _symmetricAlgorithm.CreateDecryptor(_symmetricAlgorithm.Key, _symmetricAlgorithm.IV);
		using MemoryStream stream = new MemoryStream();
		using CryptoStream cryptoStream = new CryptoStream(stream, decryptor, CryptoStreamMode.Write);
		cryptoStream.Write(encryptedData, 0, encryptedData.Length);
		cryptoStream.FlushFinalBlock();
		return stream.ToArray();
	}

	/// <summary>
	/// 加密数据
	/// </summary>
	/// <param name="originalData">原始数据</param>
	/// <returns>加密后的字节数组</returns>
	public byte[] Encrypt(byte[] originalData)
	{
		using ICryptoTransform encryptor = _symmetricAlgorithm.CreateEncryptor(_symmetricAlgorithm.Key, _symmetricAlgorithm.IV);
		using MemoryStream stream = new MemoryStream();
		using CryptoStream cryptoStream = new CryptoStream(stream, encryptor, CryptoStreamMode.Write);
		cryptoStream.Write(originalData, 0, originalData.Length);
		cryptoStream.FlushFinalBlock();
		return stream.ToArray();
	}

	/// <summary>
	/// 获取或设置初始化向量（IV）
	/// </summary>
	public byte[] IV
	{
		get => _symmetricAlgorithm.IV;
		set => _symmetricAlgorithm.IV = value;
	}

	/// <summary>
	/// 获取或设置初始化向量（IV），Base64字符串格式
	/// </summary>
	public string IVString
	{
		get => Convert.ToBase64String(_symmetricAlgorithm.IV);
		set => _symmetricAlgorithm.IV = Convert.FromBase64String(value);
	}

	/// <summary>
	/// 获取或设置加密密钥（Key）
	/// </summary>
	public byte[] Key
	{
		get => _symmetricAlgorithm.Key;
		set => _symmetricAlgorithm.Key = value;
	}

	/// <summary>
	/// 获取或设置加密密钥（Key），Base64字符串格式
	/// </summary>
	public string KeyString
	{
		get => Convert.ToBase64String(_symmetricAlgorithm.Key);
		set => _symmetricAlgorithm.Key = Convert.FromBase64String(value);
	}
}

/// <summary>
/// 对称加密算法工具类工厂，用于创建不同类型的加密算法实例
/// </summary>
public static class SymmetricCryptoUtilityFactory
{
	/// <summary>
	/// 创建AES加密实例
	/// </summary>
	/// <param name="config">可选配置，允许自定义AES算法设置</param>
	/// <returns>SymmetricCryptoUtility实例</returns>
	public static SymmetricCryptoUtility CreateAes(Func<Aes, Aes> config)
	{
		return new SymmetricCryptoUtility(config.Invoke(Aes.Create()));
	}

	/// <summary>
	/// 创建DES加密实例
	/// </summary>
	public static SymmetricCryptoUtility CreateDes() => new SymmetricCryptoUtility(DES.Create());

	/// <summary>
	/// 创建RC2加密实例
	/// </summary>
	public static SymmetricCryptoUtility CreateRc2() => new SymmetricCryptoUtility(RC2.Create());

	/// <summary>
	/// 创建Triple DES加密实例
	/// </summary>
	public static SymmetricCryptoUtility CreateTripleDes() => new SymmetricCryptoUtility(TripleDES.Create());

	/// <summary>
	/// 创建AES加密实例（Rijndael的替代品），支持自定义Key和IV
	/// </summary>
	/// <param name="key">Base64编码的Key</param>
	/// <param name="iv">Base64编码的IV</param>
	/// <returns>SymmetricCryptoUtility实例</returns>
	public static SymmetricCryptoUtility CreateRijndael(string key = "SnMxMiMhcUpFUVdFI0FzZA==", string iv = "SHVzNykoMjlIOEgyNzVeUw==")
	{
		var aes = Aes.Create();
		return new SymmetricCryptoUtility(aes)
		{
			KeyString = key,
			IVString = iv
		};
	}
}
